<template>
  <div class="ebook-reader">
    <div
      class="ebook-reader-mask"
      @click="onMaskClick"
      @touchmove="move"
      @touchend="moveEnd"
      @mousedown.left="onMouseEnter"
      @mousemove.left="onMouseMove"
      @mouseup.left="onMouseEnd"
    ></div>
    <div class="read-wrapper">
      <div id="read"></div>
    </div>
  </div>
</template>

<script>
// import { mapGetters } from 'vuex'
// import { mapActions } from 'vuex'
import Epub from 'epubjs'
import { ebookMixin } from '../../utils/mixin'
import {
  getFontFamily,
  getFontSize,
  saveFontFamily,
  saveFontSize,
  getTheme,
  saveTheme,
  getLocation
} from '../../utils/localStorage'
import { flatten } from '../../utils/book'
import { getLocalForage } from '../../utils/localForage'

global.epub = Epub
export default {
  // 放入mixin
  // computed: {
  //   // 从vuex中获取电子书路径
  //   ...mapGetters([
  //     'fileName',
  //     'menuVisible'
  //   ])
  // },
  mixins: [ebookMixin],
  methods: {
    // 1 - 鼠标进入
    // 2 - 鼠标进入后的移动
    // 3 - 鼠标从移动状态松手
    // 4 - 鼠标还原,鼠标单纯点击
    // 鼠标左键点击事件
    onMouseEnter(e) {
      // console.log('enter', e)
      this.mouseState = 1
      this.mouseStartTime = e.timeStamp
      e.preventDefault()
      e.stopPropagation()
    },
    // 鼠标移动事件
    onMouseMove(e) {
      // console.log('move', e)
      if (this.mouseState === 1) {
        this.mouseState = 2
      } else if (this.mouseState === 2) {
        let offsetY = 0
        if (this.firstOffsetY) {
          offsetY = e.clientY - this.firstOffsetY
          this.setOffsetY(offsetY)
        } else {
          this.firstOffsetY = e.clientY
        }
      }
      e.preventDefault()
      e.stopPropagation()
    },
    // 鼠标左键结束事件
    onMouseEnd(e) {
      // console.log('end', e)
      if (this.mouseState === 2) {
        this.setOffsetY(0)
        this.firstOffsetY = null
        this.mouseState = 3
      } else {
        this.mouseState = 4
      }
      // 鼠标轻微移动的纠正
      const time = e.timeStamp - this.mouseStartTime
      // 时间差小于100毫秒
      if (time < 100) {
        this.mouseState = 4
      }
      e.preventDefault()
      e.stopPropagation()
    },
    // 鼠标点击事件
    onMaskClick(e) {
      // console.log(e)
      if (this.mouseState && (this.mouseState === 2 || this.mouseState === 3)) {
        return //不处理
      }
        const offsetX = e.offsetX
        const width = window.innerWidth
        if (offsetX > 0 && offsetX < width * 0.3) {
          this.prevPage() // 点击左边 上一页
        } else if (offsetX > 0 && offsetX > width * 0.7) {
          this.nextPage() // 点击右边 下一页
        } else {
          this.toggleTitleAndMenu() // 点击中间显示标题栏菜单栏
        }
    },
    // 手势触碰移动
    move(e) {
      // console.log('move', e)
      // y轴偏移量
      let offsetY = 0
      if (this.firstOffsetY) {
        offsetY = e.changedTouches[0].clientY - this.firstOffsetY
        this.setOffsetY(offsetY)
        // console.log(offsetY)
      } else {
        this.firstOffsetY = e.changedTouches[0].clientY
        // console.log(this.firstOffsetY)
      }
      e.preventDefault()
      e.stopPropagation()
    },
    // 手势触碰移动结束
    moveEnd(e) {
      // console.log('end', e)
      this.setOffsetY(0)
      this.firstOffsetY = null
    },
    // 放入mixin
    // ...mapActions(['setMenuVisible']),
    // 前页
    prevPage() {
      if (this.rendition) {
        this.rendition.prev().then(() => {
          this.refreshLocation()
        })
        this.hideTitleAndMenu()
      }
    },
    // 后页
    nextPage() {
      if (this.rendition) {
        this.rendition.next().then(() => {
          this.refreshLocation()
        })
        this.hideTitleAndMenu()
      }
    },
    // 点击显示或隐藏标题栏和菜单栏
    toggleTitleAndMenu() {
      if (this.menuVisible) {
        // 隐藏之后再次点击屏幕 字号栏默认不显示
        this.setSettingVisible(-1)
      }
      // console.log('menu toggle')
      // this.$store.dispatch('setMenuVisible', !this.menuVisible)
      this.setMenuVisible(!this.menuVisible)
      // 隐藏字体设置栏
      this.setFontFamilyVisible(false)
    },
    // // 翻页隐藏标题栏和菜单栏 放入mixin中
    // hideTitleAndMenu() {
    //   // this.$store.dispatch('setMenuVisible', false)
    //   // 用了mapActions之后
    //   this.setMenuVisible(false)
    //   // 隐藏菜单栏之后 字号设置隐藏
    //   this.setSettingVisible(-1)
    //   // 隐藏字体设置栏
    //   this.setFontFamilyVisible(false)
    // },
    // 字号初始化存储
    initFontSize() {
      const fontSize = getFontSize(this.fileName)
      if (!fontSize) {
        saveFontSize(this.fileName, this.defaultFontSize)
      } else {
        // 书籍字体改变
        this.rendition.themes.fontSize(fontSize)
        // 字号切换栏的√变化
        this.setDefaultFontSize(fontSize)
      }
    },
    // 字体初始化存储
    initFontFamily() {
      // getFontFamily 在localStorage.js中
      const font = getFontFamily(this.fileName)
      if (!font) {
        saveFontFamily(this.fileName, this.defaultFontFamily)
      } else {
        // 书籍字体改变
        this.rendition.themes.font(font)
        // 字体切换栏的√变化
        this.setDefaultFontFamily(font)
      }
    },
    // 主题背景初始化存储
    initTheme() {
      // 主题注册
      let defaultTheme = getTheme(this.fileName)
      if (!defaultTheme) {
        defaultTheme = this.themeList[0].name
        saveTheme(this.fileName, defaultTheme)
      }
      this.setDefaultTheme(defaultTheme)
      this.themeList.forEach(theme => {
        this.rendition.themes.register(theme.name, theme.style)
      })
      this.rendition.themes.select(defaultTheme)
    },
    // 全局样式初始化存储 放到mixin中复用
    // initGlobalStyle() {
    //   switch (this.defaultTheme) {
    //     case 'Default':
    //     // 在静态资源服务中获取
    //       addCss(`${process.env.VUE_APP_RES_URL}/theme/theme_default.css`)
    //       break
    //     case 'Eye':
    //       addCss(`${process.env.VUE_APP_RES_URL}/theme/theme_Eye.css`)
    //       break
    //     case 'Gold':
    //       addCss(`${process.env.VUE_APP_RES_URL}/theme/theme_Gold.css`)
    //       break
    //     case 'Night':
    //       addCss(`${process.env.VUE_APP_RES_URL}/theme/theme_Night.css`)
    //       break
    //     default:
    //       addCss(`${process.env.VUE_APP_RES_URL}/theme/theme_default.css`)
    //       break
    //   }
    // },
    // 渲染初始化
    initRendition() {
      this.rendition = this.book.renderTo('read', {
        width: innerWidth,
        height: innerHeight,
        // 微信兼容
        method: 'default'
        // 滚动条形式阅读,微信中不能使用
        // flow: 'scrolled'
      })
      // 电子书显示,以及初始化存储
      // this.rendition.display().then(() => {
      //   this.initTheme()
      //   this.initFontSize()
      //   this.initFontFamily()
      //   this.initGlobalStyle()
      //   this.refreshLocation()
      // })
      // 改写,display 在mixin中
      const location = getLocation(this.fileName)
      // console.log(location)
      this.display(location, () => {
        this.initTheme()
        this.initFontSize()
        this.initFontFamily()
        this.initGlobalStyle()
      })
      // 添加字体样式文件,更改书籍字体
      this.rendition.hooks.content.register(contents => {
        Promise.all([
          // 括号里面是url,返回promise对象
          // contents.addStylesheet('http://218.192.172.48:8081/fonts/daysOne.css'),
          // contents.addStylesheet('http://218.192.172.48:8081/fonts/cabin.css'),
          // contents.addStylesheet('http://218.192.172.48:8081/fonts/montserrat.css'),
          // contents.addStylesheet('http://218.192.172.48:8081/fonts/tangerine.css')
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/daysOne.css`),
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/cabin.css`),
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/montserrat.css`),
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/tangerine.css`)
        ]).then(() => {
          // console.log('字体全部加载完毕。。。')
        })
      })
    },
    // 页面手势操作初始化 放到onMaskClick
    // initGesture() {
    //   this.rendition.on('touchstart', event => {
    //     // console.log(event)
    //     this.touchStartX = event.changedTouches[0].clientX
    //     this.touchStartTime = event.timeStamp
    //   })
    //   this.rendition.on('touchend', event => {
    //     // console.log(event)
    //     const offsetX = event.changedTouches[0].clientX - this.touchStartX
    //     const time = event.timeStamp - this.touchStartTime
    //     // console.log(offsetX, time)
    //     if (time < 500 && offsetX > 40) {
    //       // 从左往右滑,前页
    //       this.prevPage()
    //     } else if (time < 500 && offsetX < -40) {
    //       // 从右往左滑,后页
    //       this.nextPage()
    //     } else {
    //       // 显示标题栏
    //       this.toggleTitleAndMenu()
    //     }
    //     // 禁止事件传播
    //     event.passive = false
    //     event.stopPropagation()
    //   })
    // },
    //获取电子书内容
    parseBook() {
      // 获取封面
      this.book.loaded.cover.then(cover => {
        // console.log(cover)
        this.book.archive.createUrl(cover).then(url => {
          this.setCover(url)
          // console.log(url)
        })
      })
      // 获取封面作者和标题信息
      this.book.loaded.metadata.then(metadata => {
        this.setMetadata(metadata)
      })
      // 获取书籍目录
      this.book.loaded.navigation.then(nav => {
        // console.log(nav)
        // console.log(flatten(nav.toc))
        // 目录扁平化
        const navItem = flatten(nav.toc)
        // 获取各级目录的层级
        function find(item, level = 0) {
          return !item.parent ? level : find(navItem.filter(parentItem => parentItem.id === item.parent)[0], ++level)
        }
        navItem.forEach(item => {
          item.level = find(item)
        })
        // console.log(navItem)
        // 将处理好的目录放入vuex 的navigation中
        this.setNavigation(navItem)
      })
    },
    // 电子书初始化
    initEpub(url) {
      // 获取电子书路径
      // const url = process.env.VUE_APP_RES_URL + '/epub/' +
      //   this.fileName + '.epub'
      // console.log(`${baseUrl}${fileName}.epub`)
      // console.log(url)
      // 渲染电子书 可直接将Blob对象直接传给Epub构造函数
      this.book = new Epub(url)
      // console.log(this.book)
      // 将电子书添加到vuex中
      this.setCurrentBook(this.book)
      this.initRendition()
      // this.initGesture()
      this.parseBook()
      // 书籍的分页 ()里面是每页显示的字数
      // 默认750字数一页 16标准字号大小 粗糙的分页 有些资源文件比如图片
      // 就不是分的准确
      // 获取locations 通过Epubjs的钩子函数reader返回promise回调
      this.book.ready.then(() => {
        return this.book.locations.generate(750 * (window.innerWidth / 375) * (getFontSize(this.fileName) / 16))
      }).then((locations) => {
        // 分页算法
        this.navigation.forEach(nav => {
          // pagelist初始化，表示当前章节共有几页
          nav.pagelist = []
        })
        // locations数组 表示分页的结果
        // console.log(locations, this.navigation)
        locations.forEach(item => {
          const loc = item.match(/\[(.*)\]!/)[1]
          // 遍历目录
          this.navigation.forEach(nav => {
            if (nav.href) {
              // console.log(nav.href)
              //  xxx.html
              const href = nav.href.match(/^(.*)\.html$/)
              if (href) {
                if (href[1] === loc) {
                  // 在nav下创建pagelist push（item）
                  // 在每个章节中共有几页
                  nav.pagelist.push(item)
                }
              }
            }
          })
          // console.log(this.navigation)
          let currentPage = 1
          this.navigation.forEach((nav, index) => {
            if (index === 0) {
              nav.page = 1
            } else {
              nav.page = currentPage
            }
            // 每个章节的开始页数
            currentPage += nav.pagelist.length + 1
          })
        })
        // console.log(this.navigation)
        // 书籍总页数 存入mixin
        this.setPagelist(locations)
        // console.log(locations)
        // 进度条可使用
        this.setBookAvailable(true)
        // 刷新进度条
        this.refreshLocation()
      })
    }
  },
  mounted() {
    const books = this.$route.params.fileName.split('|')
    const fileName = books[1]
    getLocalForage(fileName, (err, blob) => {
      if (!err && blob) {
        // 离线电子书阅读
        // console.log('找到离线缓存电子书')
        this.setFileName(books.join('/')).then(() => {
          this.initEpub(blob)
        })
      } else {
        // 在线电子书阅读
        // console.log('在线获取电子书缓存电子书')
        this.setFileName(books.join('/')).then(() => {
          const url = process.env.VUE_APP_EPUB_URL + '/' +
            this.fileName + '.epub'
          this.initEpub(url)
        })
      }
    })
    // 动态路由，电子书路径转换
    // const fileName = this.$route.params.fileName.split('|').join('/')
    // this.$store.dispatch('setFileName', fileName).then(() => {
    //   this.initEpub()
    // })
    // this.setFileName(this.$route.params.fileName.split('|').join('/')).then(() => {
    //   const url = process.env.VUE_APP_RES_URL + '/epub/' +
    //     this.fileName + '.epub'
    //   this.initEpub(url)
  }
}
</script>

<style lang="scss" scoped>
@import "../../assets/styles/global";

.ebook-reader {
  width: 100%;
  height: 100%;
  overflow: hidden;
  .ebook-reader-mask {
    position: absolute;
    top: 0;
    left: 0;
    background: transparent;
    z-index: 150;
    width: 100%;
    height: 100%;
  }
}
</style>
